#include "CanBLL.h"
#include "can.h"

extern osMessageQId g_CanMsgQueueHandle;

uint32_t pTxMailbox = CAN_TX_MAILBOX0;

static struct fifo *can1_recv_fifo;
static CAN_TxHeaderTypeDef CAN_TxHeader;

struct fifo* GetCanFifoAddr(void)
{
	return can1_recv_fifo;
}

bool CanBLL_Init(void)
{
	can1_recv_fifo = fifo_alloc(CAN1_RXPACKAGE_CNT * sizeof(CanRxFrame));
	if(can1_recv_fifo	== NULL)
		return false;
	
	InitCanData();
	return true;
}

void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{
	HAL_StatusTypeDef statue;
	CanRxFrame canRxFrame;
	
	if(hcan->Instance == CAN1){
		statue = HAL_CAN_GetRxMessage(hcan,CAN_FILTER_FIFO0,
			&(canRxFrame.rxHeader),canRxFrame.rxData);
		
		if(g_CanMsgQueueHandle && (statue == HAL_OK)){
			if(can1_recv_fifo == NULL)
				return;
			
			if(canRxFrame.rxHeader.DLC == 0)
				canRxFrame.rxHeader = canRxFrame.rxHeader;
			
			fifo_in(can1_recv_fifo, (uint8_t *)&canRxFrame, sizeof(CanRxFrame));
			osMessagePut(g_CanMsgQueueHandle, (uint32_t)sizeof(CanRxFrame), 100);
		}
	}
}

static uint8_t can_sent_message_buffer[8];

static uint8_t CanAdapterSend(uint16_t can_id, uint8_t *msg,uint8_t len)
{
	uint32_t TxMailbox;//临时变量, 用于返回使用的邮箱编号
	
	CAN_TxHeader.StdId = can_id;
	CAN_TxHeader.IDE = CAN_ID_STD;
	CAN_TxHeader.RTR = CAN_RTR_DATA;
	CAN_TxHeader.DLC = len;
	
//	taskENTER_CRITICAL();
	memcpy(can_sent_message_buffer, msg, len);

	//
	while(HAL_CAN_GetTxMailboxesFreeLevel(&hcan1)== 0)
	{
		osDelay(5);
	}
	
	if(HAL_CAN_AddTxMessage(&hcan1,&CAN_TxHeader,can_sent_message_buffer,&TxMailbox) != HAL_OK)
	{
		return 1;
	}
	
	while(HAL_CAN_GetTxMailboxesFreeLevel(&hcan1) != 3)
	{
		osDelay(5);
	}
	
	while(HAL_CAN_IsTxMessagePending(&hcan1, TxMailbox) != 0)
	{
		osDelay(5);
	}
	
//	taskEXIT_CRITICAL();
	memset(can_sent_message_buffer, 0, sizeof can_sent_message_buffer);
	return 0;
}

static uint8_t can_sent_long_message_buffer[64];
void CanDeviceSendData(uint16_t can_id, uint8_t *buff,uint32_t len)
{
	uint16_t sentTimes = 0;				//发送次数
	uint8_t sentLen = 0;				//每次发送长度
	uint16_t sentcnt = 0;				//发送计次
	
	memcpy(can_sent_long_message_buffer, buff, len);
	
	if(len <= 8)
	{
		sentTimes = 1;
	}
	else
		sentTimes = len / 8 + (len % 8 ? 1 : 0);
	
	while(sentTimes--)
	{
		if(sentTimes == 0)
		{
			if(len % 8)
				sentLen = len % 8;
			else
				sentLen = 8;
		}
		else
		{
			sentLen = 8;
		}
		
		/* 发送数据 */
		CanAdapterSend(can_id, can_sent_long_message_buffer+sentcnt,sentLen);
		//这里延时至少3ms，保险起见，延时5ms。
		//原因是1包数据CAN需要的时间大约是2.8ms。
		osDelay(5);
		sentcnt += 8;
	}
}
